package com.qfxl.common.comm.parVeridy;/**
 * @Author cj
 * @Date 2023/11/23 11:34
 * @Version 1.0
 */

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author cj * @date 2023年11月23日 11:34
 */

@Aspect
@Component
public class MapParAspect {
    public MapParAspect() {
//        System.out.println("MapParAspect创建");
    }

    private static final Logger logger = LoggerFactory.getLogger(MapParAspect.class);

    @Pointcut("@annotation(org.util.common.parVeridy.MapParIntercept)")
    private void MapParIntercept() {

    }

    @Before("MapParIntercept()")
    public void interceptorDo(JoinPoint point) throws Exception {
//        try {
        logger.info("参数校验");
        //获取目标对象
        Object target = point.getTarget();
        //获取方法参数
        Object[] argements = point.getArgs();
        //获取方法名
        String methodName = point.getSignature().getName();
        //获取参数类型
        Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes();
        //反射获取该方法
        Method method = target.getClass().getMethod(methodName, parameterTypes);
        MapParIntercept interceptor = method.getAnnotation(MapParIntercept.class);
        if (interceptor == null) {
            return;
        } else {
            MapParam[] value = interceptor.value();
            if (argements.length != 0) {
                Object argement = argements[0];
                if (argement instanceof Map) {
                    Map<String, Object> reqMap = (Map<String, Object>) argement;
                    for (MapParam mapParam : value) {
                        String key = mapParam.key();
                        ParTypeEnum parTypeEnumEntity = mapParam.verifyType();
                        ParTypeEnum[] parTypeEnums = mapParam.verifyTypes();
                        if (parTypeEnums.length == 0 && parTypeEnumEntity.equals(ParTypeEnum.NONE)) {
                            continue;
                        }
                        if (parTypeEnumEntity != ParTypeEnum.NONE) {
                            List<ParTypeEnum> tempParTypeEnum = new ArrayList<>();
                            if (parTypeEnums.length != 0) {
                                tempParTypeEnum.addAll(Arrays.asList(parTypeEnums));
                            }
                            tempParTypeEnum.add(parTypeEnumEntity);
                            parTypeEnums = tempParTypeEnum.toArray(new ParTypeEnum[tempParTypeEnum.size()]);
                        }

                        for (ParTypeEnum parTypeEnum : parTypeEnums) {
                            String message = mapParam.message();
                            String type = parTypeEnum.getType();
                            if (StringUtils.isEmpty(message)) {
                                message = parTypeEnum.getMessage();
                            }
                            message = key + ":" + message;
                            //是否根据类型判断
                            boolean isTypeBoolean = parTypeEnum.isType();
                            if (VerifyCommValueInterface.notBlank.equals(type)) {
                                //判断是否为空
                                if (!reqMap.containsKey(key)) {
                                    throw new RuntimeException(message);
                                }
                            } else {
                                //判断前端传参没
                                if (!reqMap.containsKey(key)) {
                                    throw new RuntimeException(key + ":" + VerifyCommValueInterface.par_is_null);
                                }
                            }

                            Object parValue = reqMap.get(key);
                            if (isTypeBoolean) {
                                //获取数据类型
                                Class[] classes = parTypeEnum.getaClass();
                                boolean isTrue = false;
                                for (Class aClass : classes) {
                                    if (aClass.isInstance(parValue)) {
                                        isTrue = true;
                                        break;
                                    }
                                }
                                if (!isTrue) {
                                    throw new RuntimeException(message);
                                }
                            }
                            if (VerifyCommValueInterface.notBlank.equals(type)) {
                                //判断是否为空
                                if (StringUtils.isEmpty(parValue)) {
                                    throw new RuntimeException(message);
                                }
                            } else if (VerifyCommValueInterface.regex.equals(type)) {
                                //获取正则规则
                                String regexPattern = mapParam.regex();
                                //正则校验
                                Pattern pattern = Pattern.compile(regexPattern);
                                // 进行匹配
                                boolean matches = pattern.matcher(String.valueOf(parValue)).matches();
                                if (!matches) {
                                    throw new RuntimeException(message);
                                }
                            }
                        }
                    }
                }
            }

        }
        /**
         * 参数校验
         */
//        } catch (Exception e) {
//            logger.error("参数校验失败", e);
//            throw new RuntimeException(e);
//        }
        logger.info("校验成功");
    }

}
